﻿/// <reference path="../../jquery-1.10.2.js" />


var JQMove = {
    data: {
        hasBindEvent: false,
        moveEl: null, //记录当前移动的元素
        followEl: null, //记录当前跟踪移动的父对象
        eventX: 0, //鼠标单击的位置X
        eventY: 0, //鼠标单击的位置Y
        moveElX: 0, //移动对象的X坐标
        moveElY: 0 //移动对象的Y坐标
    },
    clearMove: function (el) {
        /// <summary>移除对象可移动的操作</summary>
        $(el).css({
            'cursor': 'default'
        }).children().css({
            'cursor': 'default'
        });
    },
    setMoveEl: function (el, followEl) {
        /// <summary>指定元素可以拖动</summary>
        /// <param name="el" type="DomElement/String[id]">指定元素可以移动</param>
        /// <param name="followEl" type="DomElement/String[id]">指定跟随移动的父对象，因为有一些情况，是标题获取焦点，拖动标题栏，而内容栏不能拖动的，这种情况下就可以传入标题栏对象作为移动对象，而传入标题栏的父对象作为复粘移动的对象</param>
        el = $.getJQObj(el);
        followEl = $.getJQObj(followEl);
        //如果元素非法，则不用执行了
        if (el === null) return;
        el[0].isMoveElement = true; //标志此对象是可移动对象
        $(el).bind("mousedown", { el: el, followEl: followEl }, function (e) {
            //记录事件的位置
            JQMove.data.eventX = e.pageX;
            JQMove.data.eventY = e.pageY;
            //记录对象的位置
            var moveEl = e.data.followEl || e.data.el;
            //获取移动范围的类型，一种是整个文档内部可以移动，一种是只能在父控件的范围内移动（传入父元素的ID号）
            var moveRange = e.data.el[0].moveRangeParent;
            //计算位置的时候，计算相对父节点的便宜位置，不要计算相对文档的（这样就可以控制移动元素只能在指定的范围内移动）
            var moveElOffset = null;
            //document是特定的字符串，标识文档，就是移动范围是整个文档内部的
            if (moveRange && moveRange !== 'document') {
                var moveRangeEl = $.getJQObj(moveRange)[0];
                //节点的父元素到指定范围的父元素的偏移量（需要减去这个偏移量，因为这个位置absolute是相对父元素的，如果移动范围不是这个范围的父元素，则需要计算这个父节点到父节点的偏移）
                var parentOffset = $(e.data.el[0].parentNode).offsetEx(moveRangeEl);
                //alert(moveRangeEl.id);
                moveElOffset = $(moveEl).offsetEx(moveRangeEl);
                if (parentOffset) {
                    moveElOffset.left = moveElOffset.left - parentOffset.left;
                    moveElOffset.top = moveElOffset.top - parentOffset.top;
                }
            }
            else {
                moveElOffset = $(moveEl).offsetEx();
            }
            //moveElOffset = $(moveEl).offsetEx($(moveEl)[0].parentNode);
            JQMove.data.moveElX = moveElOffset.left;
            JQMove.data.moveElY = moveElOffset.top;
            //记录移动对象
            JQMove.data.moveEl = e.data.el;
            JQMove.data.followEl = e.data.followEl;
            //必须停止事件的传播，否则如果父元素也可以移动的话，则无法移动其子元素了
            e.stopPropagation();
            //触发获取焦点的事件
            $(this).focus();
        }).bind("focusin", function () {
            //判断对象是否设置了border属性，如果设置了border属性，还需要通过css设置border属性，如果对象没有设置，则不需要了
            var border = $(this).css('border');
            //提高层次
            $(this).css({
                'z-index': $.zIndex++
            });
            if (border) {
                $(this)[0].oldBorder = border;
                $(this).addClass('highlightEl').css('border', '1px solid red');
            }
            else {
                $(this).addClass('highlightEl');
            }
        }).bind("focusout ", function (e) {
            //失去焦点的时候，更换样式
            //切换样式
            var hilightEls = $('.highlightEl');
            if (hilightEls.length > 0) {
                var oldBorder = hilightEls[0].oldBorder;
                hilightEls.removeClass('highlightEl').css('border', oldBorder);
            }
        }).css({
            'cursor': 'move'
        }).children().css({
            'cursor': 'move'
        });

        //先判断是否绑定了document的移动事件
        if (!JQMove.data.hasBindEvent) {
            JQMove.data.hasBindEvent = true;
            $(document).bind("mousemove", function (e) {
                //只有鼠标左击松开的时候才触发事件
                if (e.which === 1) {
                    //如果有跟踪移动对象的话，则移动跟踪对象即可
                    var moveEl = JQMove.data.followEl || JQMove.data.moveEl;
                    if (!moveEl) return;
                    //捕获事件 在iframe的情况下，很有必要的
                    moveEl[0].setCapture();
                    $(moveEl).attr("unselectable", "on");
                    $(JQMove.data.moveEl).attr("unselectable", "on");

                    //需要计算最小的坐标
                    var minLeft = 0, minTop = 0;
                    //获取移动范围的类型，一种是整个文档内部可以移动，一种是只能在父控件的范围内移动（传入父元素的ID号）
                    var moveRange = JQMove.data.moveEl[0].moveRangeParent;
                    //计算位置的时候，计算相对父节点的便宜位置，不要计算相对文档的（这样就可以控制移动元素只能在指定的范围内移动）
                    var moveElOffset = null;
                    //document是特定的字符串，标识文档，就是移动范围是整个文档内部的
                    if (moveRange && moveRange !== 'document') {
                        var moveRangeEl = $.getJQObj(moveRange)[0];
                        //节点的父元素到指定范围的父元素的偏移量（需要减去这个偏移量，因为这个位置absolute是相对父元素的，如果移动范围不是这个范围的父元素，则需要控制这个移动范围）
                        var parentOffset = $(JQMove.data.moveEl[0].parentNode).offsetEx(moveRangeEl);
                        minLeft = -1 * parentOffset.left;
                        minTop = -1 * parentOffset.top;
                    }

                    var left = Math.max((e.pageX - JQMove.data.eventX + JQMove.data.moveElX), minLeft);
                    var top = Math.max((e.pageY - JQMove.data.eventY + JQMove.data.moveElY), minTop);

                    //window.status = e.pageX + ";" + e.pageY;
                    $(moveEl).css({
                        'left': left + 'px',
                        'top': top + 'px',
                        'position': 'absolute'
                    });
                }
            }).bind("mouseup", function (e) {
                //只有鼠标左击松开的时候才触发事件
                if (e.which === 1) {
                    //在释放鼠标前，会触发一个自定义的事件beforeCancelMove
                    //e是传入自定义事件的参数
                    $(this).trigger("beforeCancelMove", e);
                    JQMove.cancelMove();
                    //在释放鼠标后，会触发一个自定义的事件afterCancelMove
                    $(this).trigger("afterCancelMove", e);
                }
            });
        }
    },
    cancelMove: function () {
        /// <summary>重置配置，取消移动</summary>
        var moveEl = JQMove.data.followEl || JQMove.data.moveEl;
        if (moveEl) moveEl[0].releaseCapture();
        JQMove.data.eventX = 0;
        JQMove.data.eventY = 0;
        JQMove.data.moveElX = 0;
        JQMove.data.moveElY = 0;
        JQMove.data.moveEl = null;
        JQMove.data.followEl = null;
    }
};
